﻿using Protocol.SouthGridProtocol.Blocks;//
using PacoToolKit.Format;
using System;

namespace Protocol.SouthGridProtocol.Encoder
{
    /// <summary>
    /// 基础组帧编码器
    /// </summary>
    public class BaseEncoder
    {
        public static string CreateAnswerMsg(string c, string concentratorDomain, string seq)
        {
            //生成c
            C tempC = new C(c);
            tempC.dir = 0;//主站发出的下行报文
            tempC.prm = 0;//从动
            tempC.funcCode = 11;//对应PRM=1，链路层功能码=09的确认/否认
            string c_block = tempC.encodeC();
            //生成seq
            Seq tempSeq = new Seq(seq);
            tempSeq.con = 0;//不确认
            string seq_block = tempSeq.encodeSeqString();
            //其他

            string concentrator_block = concentratorDomain;
            //string concentrator_block = concentrator.Substring(0, 12) + "01";
            string afn_block = "00";
            string da_block = "0000";
            string di_block = "000000E0";//全部确定/否定
            string data_block = "00";//肯定
            //
            string length_block = BaseEncoder.CalcLength(c_block + concentrator_block + afn_block + seq_block + da_block + di_block + data_block);
            string cs_block = BaseEncoder.CalcCSCode(Formater.HexStringToBytesKeep(c_block + concentrator_block + afn_block + seq_block + da_block + di_block + data_block)).ToString("X2");
            return "68" + length_block + length_block + "68" + c_block + concentrator_block + afn_block + seq_block + da_block + di_block + data_block + cs_block + "16";
        }

        /// <summary>
        /// 计算长度
        /// </summary>
        /// <param name="blocks">报文内容:包括控制域、地址域、链路用户数据（应用层）的字节总数</param>
        /// <returns></returns>
        public static string CalcLength(string blocks)
        {

            int len = blocks.Length / 2;
            return Formater.ReverseHexString(Formater.DECtoHEX(len.ToString(), 4)).ToUpper();
        }
        public static byte CalcCSCode(byte[] bytes)
        {
            int temp = 0;
            for (int i = 0; i < bytes.Length; i++)
            {
                temp = temp + Convert.ToInt32(bytes[i]);
            }
            return Convert.ToByte(temp % 256);
        }
        public static string CalcCSCode(string str)
        {
            return Formater.CalcCSCode(str);
        }
        /// <summary>
        /// 生产TP
        /// </summary>
        /// <returns></returns>
        public static string CreateTP()
        {
            string time = DateTime.Now.ToString("dd") + DateTime.Now.ToString("HH") + DateTime.Now.ToString("mm") + DateTime.Now.ToString("ss");
            string timeout = "00";
            return Formater.ReverseHexString(time) + timeout;
        }
        /// <summary>
        /// 根据测量点号计算da
        /// </summary>
        /// <param name="tn">测量点号</param>
        /// <returns></returns>
        public static string CalcDa(string tn)
        {
            if (int.Parse(tn).Equals(0))
            {
                return "0000";
            }
            else
            {
                string DA1, DA2, tnGroupIndex, mod;
                mod = ((int.Parse(tn)) % 8).ToString();
                if (mod.Equals("0"))
                {
                    tnGroupIndex = (int.Parse(tn) / 8).ToString();// 组号
                    DA2 = Formater.DECtoHEX(tnGroupIndex, 2);//DA2 hex
                    DA1 = "80";//DA1 hex
                }
                else
                {
                    tnGroupIndex = (int.Parse(tn) / 8 + 1).ToString();//DA2 组号
                    DA2 = Formater.DECtoHEX(tnGroupIndex, 2);//DA2 hex
                    DA1 = Formater.DECtoHEX((1 << (int.Parse(mod) - 1)).ToString(), 2);//DA1 hex
                }
                return (DA1 + DA2).ToUpper();
            }
        }
        /// <summary>
        /// 连续组合测量点号计算da
        /// </summary>
        /// <param name="tnArray">由小到大连续的数字数组</param>
        /// <returns></returns>
        public static string CalcDa(string[] tnArray)
        {
            //tnArray必须是由小到大连续的数字
            string DA2Max = "00";
            int DA1Count = 0;
            foreach (string tn in tnArray)
            {
                string DA = CalcDa(tn); string DA1 = DA.Substring(0, 2); string DA2 = DA.Substring(2, 2);

                //找出最大的DA2
                if (int.Parse(Formater.HEXtoDEC(DA2)) > int.Parse(Formater.HEXtoDEC(DA2Max)))
                {
                    //交换
                    DA2Max = DA2;
                }
                //叠加出di1总和
                DA1Count = DA1Count + int.Parse(Formater.HEXtoDEC(DA1));
            }

            //组合最大da2和da1总和，得到结果
            return Formater.DECtoHEX(DA1Count.ToString(), 2) + DA2Max;
        }
    }
}
